package com.fingard.dsp.bank.directbank.weixin01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.text.SplitHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * WEIXIN01-微信财付通渠道对账单
 *
 * @author Cruise
 * @Version 1.0
 */
public class WEIXIN01Statement extends WEIXIN01Base implements IStatement {
	public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
		RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
		retAts.writeStart();

		String[] unifiedOrderRespHeader = getUnifiedOrderStatement(p_reqQrySttm, retAts);
		String unifiedOrderTotalNum = retAts.totalNum;
		if ("".equals(unifiedOrderTotalNum)) {
			unifiedOrderTotalNum = "0";
		}

		String[] paymentRespHeader = getPaymentStatement(p_reqQrySttm, retAts);
		String paymentTotalNum = retAts.totalNum;
		if ("".equals(paymentTotalNum)) {
			paymentTotalNum = "0";
		}

		if ("-1".equals(unifiedOrderRespHeader[0]) && "-1".equals(paymentRespHeader[0])) {
			retAts.writeRespCode("-1");
			retAts.writeRespInfo("统一下单对账单获取失败,原因:" + unifiedOrderRespHeader[1] + ";企业付款对账单获取失败,原因:" + paymentRespHeader[1]);
		} else {
			if (retAts.getWrittenRdCount() == 0) {
				retAts.writeRespCode("0");
				String respInfo = unifiedOrderRespHeader[1];
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = paymentRespHeader[1];
				}
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = "交易为空";
				}
				retAts.writeRespInfo(respInfo);
			}
			retAts.isWritedTotalNum(String.valueOf(Integer.parseInt(unifiedOrderTotalNum) + Integer.parseInt(paymentTotalNum)));
		}

		retAts.writeEnd();
		return retAts;
	}

	/**
	 * 统一下单对账单获取
	 * 
	 * <p>接口文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6</p>
	 * 
	 * @param p_reqQrySttm
	 * @param retAts
	 * @return
	 */
	public String[] getUnifiedOrderStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) {
		String[] tmpRespHeader = new String[] { "", "" };

		String tmpRespCode = "";
		String tmpRespInfo = "";
		retAts.totalNum = "0";
		int totalNum = 0;

		try {
			ActSetItem actItem = getBankConfig().getActSetItemByAny(p_reqQrySttm.actNum, "", "", "unifiedorder");
			if (actItem != null) {
				StringBuilder sbXml = new StringBuilder();
				ArrayList<String> arrayParams = new ArrayList<String>();

				sbXml.append("<xml>\r\n");
				sbXml.append("  <appid>" + actItem.appId + "</appid>\r\n");
				arrayParams.add("appid=" + actItem.appId);

				String mch_id = actItem.merchantId;
				sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
				arrayParams.add("mch_id=" + mch_id);

				String nonce_str = get_nonce_str();
				sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
				arrayParams.add("nonce_str=" + nonce_str);

				sbXml.append("  <bill_date>" + p_reqQrySttm.busDate + "</bill_date>\r\n");
				arrayParams.add("bill_date=" + p_reqQrySttm.busDate);

				String bill_type = getBankConfig().getValueAsString("bill_type");
				if (StringHelper.isNullOrEmpty(bill_type)) {
					bill_type = "ALL";
				}
				sbXml.append("  <bill_type>" + bill_type + "</bill_type>\r\n");
				arrayParams.add("bill_type=" + bill_type);

				String[] signParams = new String[arrayParams.size()];
				arrayParams.toArray(signParams);
				String sign = signMessage(signParams, actItem.saltKey);
				sbXml.append("  <sign>" + sign + "</sign>\r\n");
				sbXml.append("</xml>");

				String[] tmpStrRet = sendToBank(sbXml.toString(), "downloadbill");

				if (tmpStrRet[0].length() == 0) {
					if (tmpStrRet[1].indexOf("<xml") >= 0) {// 无对账单
						StringBuilder tmpSbMsg = new StringBuilder();
						XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
						if (tmpBkReader != null) {
							String return_code = tmpBkReader.getFirstText("/xml/return_code");
							String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
							String error_code = tmpBkReader.getFirstText("/xml/error_code");
							tmpRespInfo = StringHelper.joinNotEmpty("-", error_code, return_msg);
							if (!return_code.equals("FAIL") || return_msg.equals("No Bill Exist")) {
								tmpRespCode = "0";
							} else {
								tmpRespCode = "-1";
							}
						} else {
							tmpRespCode = "-1";
							tmpRespInfo = tmpSbMsg.toString();
						}
					} else {
						tmpRespCode = "0";

						StringReader strReader = new StringReader(tmpStrRet[1]);
						BufferedReader tmpReader = new BufferedReader(strReader);

						int int1 = 65279;
						String line1 = tmpReader.readLine();
						int idxHdChar = line1.indexOf(int1);
						if (idxHdChar >= 0) {
							line1 = line1.substring(idxHdChar + 1);
						}
						String[] columns = line1.split(",");
						while (true) {
							//交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,代金券或立减优惠金额,微信退款单号,商户退款单号,退款金额,代金券或立减优惠退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率
							String eachline = tmpReader.readLine();
							if (eachline == null) {
								break;
							}
							String[] values = eachline.split(",");
							if (columns.length == values.length) {
								HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
								RetAtsStatementDetail retDetail = new RetAtsStatementDetail();

								totalNum++;
								if (mapKV.containsKey("总金额")) {
									retDetail.amount = mapKV.get("总金额").replace("`", "");
								}
								if (mapKV.containsKey("订单金额")) {
									retDetail.amount = mapKV.get("订单金额").replace("`", "");
								}
								if (mapKV.containsKey("交易时间")) {
									retDetail.busTime = mapKV.get("交易时间").replace("`", "").replace("-", "").replace(":", "").replace(" ", "");
								}
								if (mapKV.containsKey("商户订单号")) {
									retDetail.askNumber = mapKV.get("商户订单号").replace("`", "");
								}

								if (mapKV.containsKey("交易状态")) {
									if (mapKV.get("交易状态").replace("`", "").toUpperCase().equals("SUCCESS")) {
										retDetail.transState = TransState.Success;
									} else {
										retDetail.transState = TransState.Exception;
									}
									if (mapKV.get("交易状态").replace("`", "").toUpperCase().equals("REFUND")) {
										if (mapKV.containsKey("退款金额")) {
											retDetail.amount = mapKV.get("退款金额").replace("`", "");
										}
									}
								}
								if (mapKV.containsKey("付款银行")) {
									retDetail.oppBank = mapKV.get("付款银行").replace("`", "");
								}
								if (mapKV.containsKey("商户数据包")) {
									retDetail.memo = mapKV.get("商户数据包").replace("`", "");
								}
								if (mapKV.containsKey("手续费")) {
									double fee = Double.parseDouble(mapKV.get("手续费").replace("`", ""));
									retDetail.fee = Format.DecimalAmtFormat.format(fee);
								}
								if (mapKV.containsKey("用户标识")) {
									retDetail.oppAct = mapKV.get("用户标识").replace("`", "");
								}
								if (mapKV.containsKey("设备号")) {
									retDetail.termCode = mapKV.get("设备号").replace("`", "");
								}
								if (mapKV.containsKey("微信订单号")) {
									retDetail.bkSeq = mapKV.get("微信订单号").replace("`", "");
								}
								retDetail.cdFlag = "22";

								if (mapKV.containsKey("退款类型")) {
									String refundType = mapKV.get("退款类型").replace("`", "");
									if (StringHelper.hasAnyChar(refundType)) {
										// 退款对账单
										if (mapKV.containsKey("商户退款单号")) {
											retDetail.askNumber = mapKV.get("商户退款单号").replace("`", "");
										}
										retDetail.cdFlag = "27";
										retDetail.transState = TransState.ToRefund;
									}
								}

								retAts.writeRetDetail(retDetail);
							} else {
								break;
							}
						}
					}
				} else {
					tmpRespCode = "-1";
					tmpRespInfo = tmpStrRet[1];
				}
			} else {
				tmpRespCode = "-1";
				tmpRespInfo = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.totalNum = String.valueOf(totalNum);
		tmpRespHeader[0] = tmpRespCode;
		tmpRespHeader[1] = tmpRespInfo;
		return tmpRespHeader;
	}

	/**
	 * 企业付款对账单获取
	 * 
	 * <p>接口文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_18&index=7</p>
	 * 
	 * @param p_reqQrySttm
	 * @param retAts
	 * @return
	 */
	public String[] getPaymentStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) {
		String[] tmpRespHeader = new String[] { "", "" };

		String tmpRespCode = "";
		String tmpRespInfo = "";
		retAts.totalNum = "0";
		int totalNum = 0;

		try {
			ActSetItem actItem = this.getBankConfig().getActSetItemByAny(p_reqQrySttm.actNum, "", "", "wxpay");
			if (actItem != null) {
				StringBuilder sbXml = new StringBuilder();
				ArrayList<String> arrayParams = new ArrayList<String>();

				sbXml.append("<xml>\r\n");
				String appid = actItem.appId;
				sbXml.append("  <appid>" + appid + "</appid>\r\n");
				arrayParams.add("appid=" + appid);

				String mch_id = actItem.merchantId;
				sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
				arrayParams.add("mch_id=" + mch_id);

				String nonce_str = get_nonce_str();
				sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
				arrayParams.add("nonce_str=" + nonce_str);

				sbXml.append("  <sign_type>HMAC-SHA256</sign_type>\r\n");
				arrayParams.add("sign_type=HMAC-SHA256");

				sbXml.append("  <bill_date>" + p_reqQrySttm.busDate + "</bill_date>\r\n");
				arrayParams.add("bill_date=" + p_reqQrySttm.busDate);

				String account_type = getBankConfig().getValueAsString("account_type");
				if (StringHelper.isNullOrEmpty(account_type)) {
					account_type = "Basic";
				}
				sbXml.append("  <account_type>" + account_type + "</account_type>\r\n");
				arrayParams.add("account_type=" + account_type);

				String[] signParams = new String[arrayParams.size()];
				arrayParams.toArray(signParams);

				String sign = signMessage(signParams, actItem.saltKey);
				sbXml.append("  <sign>" + sign + "</sign>\r\n");
				sbXml.append("</xml>");

				// 发送微信并获取返回
				String[] tmpStrRet = sendToBank(sbXml.toString(), "paymentStatement", actItem);
				if (tmpStrRet[0].length() == 0) {
					if (tmpStrRet[1].indexOf("<xml") >= 0) {// 无对账单
						StringBuilder tmpSbMsg = new StringBuilder();
						XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

						if (tmpBkReader != null) {
							String return_code = tmpBkReader.getFirstText("/xml/return_code");
							String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
							String error_code = tmpBkReader.getFirstText("/xml/error_code");
							tmpRespInfo = StringHelper.joinNotEmpty("-", error_code, return_msg);
							if (!return_code.equals("FAIL") || return_msg.equals("No Bill Exist")) {
								tmpRespCode = "0";
							} else {
								tmpRespCode = "-1";
							}
						} else {
							tmpRespCode = "-1";
							tmpRespInfo = tmpSbMsg.toString();
						}
					} else {
						tmpRespCode = "0";

						StringReader strReader = new StringReader(tmpStrRet[1]);
						BufferedReader tmpReader = new BufferedReader(strReader);

						int int1 = 65279;
						String line1 = tmpReader.readLine();
						int idxHdChar = line1.indexOf(int1);
						if (idxHdChar >= 0) {
							line1 = line1.substring(idxHdChar + 1);
						}
						String[] columns = line1.split(",");
						while (true) {
							String eachline = tmpReader.readLine();
							if (eachline == null) {
								break;
							}
							String[] values = eachline.split(",");
							if (columns.length == values.length) {
								HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
								RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();
								totalNum++;
								// 每笔明细记录：记账时间,微信支付业务单号,资金流水单号,业务名称,业务类型,收支类型,收支金额（元）,账户结余（元）,资金变更提交申请人,备注,业务凭证号
								if (mapKV.containsKey("收支金额（元）")) {
									tmpRetDetail.amount = mapKV.get("收支金额（元）").replace("`", "");
								}
								if (mapKV.containsKey("记账时间")) {
									tmpRetDetail.busTime = mapKV.get("记账时间").replace("`", "").replace("-", "").replace(":", "").replace(" ", "");
								}
								if (mapKV.containsKey("资金流水单号")) {
									tmpRetDetail.askNumber = mapKV.get("资金流水单号").replace("`", "");
								}
								if (mapKV.containsKey("微信支付业务单号")) {
									tmpRetDetail.bkSeq = mapKV.get("微信支付业务单号").replace("`", "");
								}
								tmpRetDetail.transState = TransState.Success;
								tmpRetDetail.cdFlag = "27";
								retAts.writeRetDetail(tmpRetDetail);
							} else {
								break;
							}
						}
					}
				} else {
					tmpRespCode = "-1";
					tmpRespInfo = tmpStrRet[1];
				}
			} else {
				tmpRespCode = "-1";
				tmpRespInfo = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.totalNum = String.valueOf(totalNum);
		tmpRespHeader[0] = tmpRespCode;
		tmpRespHeader[1] = tmpRespInfo;
		return tmpRespHeader;
	}
}
